#region

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using log4net;
using xConnected.Core.Interfaces.Service;
using xConnected.Core.Model.ViewModel;

#endregion

namespace xConnected.Web.Controllers
{
    public class MessageFolderController : ApiController
    {
        protected const string pp = "pp";
        protected const string cp = "cp";
        protected const string pr = "pr";
        protected IMessageFolderService MessageFolderService;
        protected IMessageService MessageService;
        protected IUserService UserService;

        public MessageFolderController(IMessageFolderService messageFolderService, IMessageService messageService,
                                       IUserService userService)
        {
            MessageFolderService = messageFolderService;
            MessageService = messageService;
            UserService = userService;
        }

        public IEnumerable<MessageFolderViewModel> List()
        {
            ILog log = LogManager.GetLogger(GetType());
            try
            {
                var userId = UserService.GetUserByUsername(User.Identity.Name).Id;

                var foldersList = MessageFolderService.GetAll().Where(m => m.OwnerId == userId);

                var folders = MessageFolderService.GetAll().Where(m => m.OwnerId == userId).OrderBy(m => m.FolderType).
                    ToList().
                    Select(m => new
                                    {
                                        m.Created,
                                        m.Updated,
                                        m.Id,
                                        m.OwnerId,
                                        m.Name,
                                        m.FolderType,
                                        Messages =
                                    m.MessageExpertUsers.Select(mu => mu.Message).Union(
                                        m.MessageCompanyUsers.Select(mc => mc.Message)).Union(
                                            m.MessagePositionUsers.Select(mp => mp.Message)).Where(
                                                me => me.Children.Count == 0).Distinct().OrderByDescending(
                                                    me => me.Id).Select(me => new
                                                                                  {
                                                                                      me.Id,
                                                                                      me.Created,
                                                                                      me.Updated,
                                                                                      me.Subject,
                                                                                      me.Body,
                                                                                      me.IsChecked,
                                                                                      BodyShort = me.Body.Length > 50 ? me.Body.Substring(0, 50) + "..." : me.Body,
                                                                                      me.AllRecipientsVisible,
                                                                                      Sender = me.MessageExpertUsers.Where(mp => mp.IsSender).Select(s => new
                                                                                    {
                                                                                        s.Id,
                                                                                        s.ExpertProfile.Title,
                                                                                        s.ExpertProfile.Description,
                                                                                        s.ExpertProfile.Photo,
                                                                                        UserType = pp,
                                                                                        s.IsRead,
                                                                                        s.IsStarred,
                                                                                        s.IsDeleted
                                                                                    })
                                                                                  .Union(me.MessageCompanyUsers.Where(mc => mc.IsSender).Select(s => new
                                                                                    {
                                                                                        s.Id,
                                                                                        s.CompanyProfile.Title,
                                                                                        s.CompanyProfile.Description,
                                                                                        s.CompanyProfile.Photo,
                                                                                        UserType = cp,
                                                                                        s.IsRead,
                                                                                        s.IsStarred,
                                                                                        s.IsDeleted
                                                                                    }))
                                                                                  .Union(me.MessagePositionUsers.Where(mc => mc.IsSender).Select(s => new
                                                                                    {
                                                                                        s.Id,
                                                                                        s.Position.Title,
                                                                                        s.Position.Description,
                                                                                        s.Position.Photo,
                                                                                        UserType = pr,
                                                                                        s.IsRead,
                                                                                        s.IsStarred,
                                                                                        s.IsDeleted
                                                                                    })).FirstOrDefault(),
                                                                                      Receivers = me.MessageExpertUsers.Where(mp => !mp.IsSender).Select(s => new
                                                                                                   {
                                                                                                       s.Id,
                                                                                                       s.ExpertProfile.Title,
                                                                                                       s.ExpertProfile.Description,
                                                                                                       s.ExpertProfile.Photo,
                                                                                                       UserType = pp,
                                                                                                       s.IsRead,
                                                                                                       s.IsStarred,
                                                                                                       s.IsDeleted
                                                                                                   }).Union(me.MessageCompanyUsers.Where(mc => !mc.IsSender).Select(s => new
                                                                                                    {
                                                                                                        s.Id,
                                                                                                        s.CompanyProfile.Title,
                                                                                                        s.CompanyProfile.Description,
                                                                                                        s.CompanyProfile.Photo,
                                                                                                        UserType = cp,
                                                                                                        s.IsRead,
                                                                                                        s.IsStarred,
                                                                                                        s.IsDeleted
                                                                                                    })).Union(me.MessagePositionUsers.Where(mc => !mc.IsSender).Select(s => new
                                                                                                       {
                                                                                                           s.Id,
                                                                                                           s.Position.Title,
                                                                                                           s.Position.Description,
                                                                                                           s.Position.Photo,
                                                                                                           UserType = pr,
                                                                                                           s.IsRead,
                                                                                                           s.IsStarred,
                                                                                                           s.IsDeleted
                                                                                                       })),
                                                                                      Children = MessageService.GetAll().Where(cm => cm.ParentId == me.ParentId ||cm.Id == me.ParentId).OrderBy(cm => cm.Id).Select(cm => new
                                                                                                                        {
                                                                                                                            cm.Id,
                                                                                                                            cm.Created,
                                                                                                                            cm.Updated,
                                                                                                                            cm.Subject,
                                                                                                                            cm.Body,
                                                                                                                            BodyShort = cm.Body.Length > 50 ? cm.Body.Substring(0, 50) + "..." : cm.Body,
                                                                                                                            cm.AllRecipientsVisible,
                                                                                                                            //cm.IsChecked,
                                                                                                                            Sender = cm.MessageExpertUsers.Where(mp => mp.IsSender).Select(s => new
                                                                                                                             {
                                                                                                                                 s.Id,
                                                                                                                                 s.ExpertProfile.Title,
                                                                                                                                 s.ExpertProfile.Description,
                                                                                                                                 s.ExpertProfile.Photo,
                                                                                                                                 UserType = pp,
                                                                                                                                 s.IsRead,
                                                                                                                                 s.IsStarred,
                                                                                                                                 s.IsDeleted
                                                                                                                             })
                                                                                                                        .Union(cm.MessageCompanyUsers.Where(mc => mc.IsSender).Select(s => new
                                                                                                                                     {
                                                                                                                                         s.Id,
                                                                                                                                         s.CompanyProfile.Title,
                                                                                                                                         s.CompanyProfile.Description,
                                                                                                                                         s.CompanyProfile.Photo,
                                                                                                                                         UserType = cp,
                                                                                                                                         s.IsRead,
                                                                                                                                         s.IsStarred,
                                                                                                                                         s.IsDeleted
                                                                                                                                     }))
                                                                                                                        .Union(cm.MessagePositionUsers.Where(mc => mc.IsSender).Select(s => new
                                                                                                                                     {
                                                                                                                                         s.Id,
                                                                                                                                         s.Position.Title,
                                                                                                                                         s.Position.Description,
                                                                                                                                         s.Position.Photo,
                                                                                                                                         UserType = pr,
                                                                                                                                         s.IsRead,
                                                                                                                                         s.IsStarred,
                                                                                                                                         s.IsDeleted
                                                                                                                                     })).FirstOrDefault(),
                                                                                                                            Receivers = cm.MessageExpertUsers.Where(mp => !mp.IsSender).Select(s => new
                                                                                                                             {
                                                                                                                                 s.Id,
                                                                                                                                 s.ExpertProfile.Title,
                                                                                                                                 s.ExpertProfile.Description,
                                                                                                                                 s.ExpertProfile.Photo,
                                                                                                                                 UserType = pp,
                                                                                                                                 s.IsRead,
                                                                                                                                 s.IsStarred,
                                                                                                                                 s.IsDeleted
                                                                                                                             })
                                                                                                                        .Union(cm.MessageCompanyUsers.Where(mc => !mc.IsSender).Select(s => new
                                                                                                                                     {
                                                                                                                                         s.Id,
                                                                                                                                         s.CompanyProfile.Title,
                                                                                                                                         s.CompanyProfile.Description,
                                                                                                                                         s.CompanyProfile.Photo,
                                                                                                                                         UserType = cp,
                                                                                                                                         s.IsRead,
                                                                                                                                         s.IsStarred,
                                                                                                                                         s.IsDeleted
                                                                                                                                     }))
                                                                                                                        .Union(cm.MessagePositionUsers.Where(mc => !mc.IsSender).Select(s => new
                                                                                                                                     {
                                                                                                                                         s.Id,
                                                                                                                                         s.Position.Title,
                                                                                                                                         s.Position.Description,
                                                                                                                                         s.Position.Photo,
                                                                                                                                         UserType= pr,
                                                                                                                                         s.IsRead,
                                                                                                                                         s.IsStarred,
                                                                                                                                         s.IsDeleted
                                                                                                                                     }))
                                                                                                                        })
                                                                                  })
                                    });
                var messageFolders = new List<MessageFolderViewModel>();
                foreach (var messageFolder in folders)
                {
                    var messageFolderModel = new MessageFolderViewModel
                                                 {
                                                     Id = messageFolder.Id,
                                                     Created = messageFolder.Created,
                                                     Updated = messageFolder.Updated,
                                                     OwnerId = messageFolder.OwnerId,
                                                     Name = messageFolder.Name,
                                                     FolderType = messageFolder.FolderType
                                                 };

                    messageFolder.Messages.ToList().ForEach(message =>
                                                                {
                                                                    var messageModel = new MessageViewModel
                                                                                           {
                                                                                               Id = message.Id,
                                                                                               Created = message.Created,
                                                                                               Updated = message.Updated,
                                                                                               Subject = message.Subject,
                                                                                               Body = message.Body,
                                                                                               IsChecked = message.IsChecked,
                                                                                               Sender =
                                                                                                   {
                                                                                                       Id = message.Sender.Id,
                                                                                                       Title = message.Sender.Title,
                                                                                                       Description = message.Sender.Description,
                                                                                                       Photo = message.Sender.Photo,
                                                                                                       UserType = message.Sender.UserType,
                                                                                                       IsRead = message.Sender.IsRead,
                                                                                                       IsStarred = message.Sender.IsStarred,
                                                                                                       IsDeleted = message.Sender.IsDeleted
                                                                                                   }
                                                                                           };
                                                                    message.Receivers.Select(receiver => new MessageUserViewModel
                                                                                        {
                                                                                            Id = receiver.Id,
                                                                                            Title = receiver.Title,
                                                                                            Description = receiver.Description,
                                                                                            Photo = receiver.Photo,
                                                                                            UserType = receiver.UserType,
                                                                                            IsRead = receiver.IsRead,
                                                                                            IsStarred = receiver.IsStarred,
                                                                                            IsDeleted = receiver.IsDeleted
                                                                                        }).ToList().ForEach(m => messageModel.Receivers.Add(m));
                                                                    message.Children.ToList().ForEach(childMessage =>
                                                                                                             {
                                                                                                                 var childMessageModel = new MessageViewModel
                                                                                                                                       {
                                                                                                                                           Id = childMessage.Id,
                                                                                                                                           Created = childMessage.Created,
                                                                                                                                           Updated = childMessage.Updated,
                                                                                                                                           Subject = childMessage.Subject,
                                                                                                                                           Body = childMessage.Body,
                                                                                                                                           //IsChecked = childMessage.IsChecked,
                                                                                                                                           Sender =
                                                                                                                                               {
                                                                                                                                                   Id = childMessage.Sender.Id,
                                                                                                                                                   Title = childMessage.Sender.Title,
                                                                                                                                                   Description = childMessage.Sender.Description,
                                                                                                                                                   Photo = childMessage.Sender.Photo,
                                                                                                                                                   UserType = childMessage.Sender.UserType,
                                                                                                                                                   IsRead = childMessage.Sender.IsRead,
                                                                                                                                                   IsStarred = childMessage.Sender.IsStarred,
                                                                                                                                                   IsDeleted = childMessage.Sender.IsDeleted
                                                                                                                                               }
                                                                                                                                       };
                                                                                                                 childMessage.Receivers.Select(childReceiver => new MessageUserViewModel
                                                                                                                          {
                                                                                                                              Id = childReceiver.Id,
                                                                                                                              Title = childReceiver.Title,
                                                                                                                              Description = childReceiver.Description,
                                                                                                                              Photo = childReceiver.Photo,
                                                                                                                              UserType = childReceiver.UserType,
                                                                                                                              IsRead = childReceiver.IsRead,
                                                                                                                              IsStarred = childReceiver.IsStarred,
                                                                                                                              IsDeleted = childReceiver.IsDeleted
                                                                                                                          }).ToList().ForEach(c => childMessageModel.Receivers.Add(c));
                                                                                                                 messageModel.Children.Add(childMessageModel);
                                                                                                             });
                                                                    messageFolderModel.Messages.Add(messageModel);
                                                                });
                    messageFolders.Add(messageFolderModel);
                }

                #region 
                //var inbox = MessageFolderService.GetAll().First(m => m.OwnerId == userId && m.FolderType == 0);
                //var unreadMesInbox = inbox.MessageExpertUsers.Select(mp => new
                //                                                                      {
                //                                                                          mp.Id,
                //                                                                          mp.IsRead,
                //                                                                          mp.IsSender
                //                                                                      }).Union(
                //                                                                          inbox.MessageCompanyUsers.
                //                                                                              Select(mp => new
                //                                                                                               {
                //                                                                                                   mp.Id,
                //                                                                                                   mp.IsRead,
                //                                                                                                   mp.IsSender
                //                                                                                               })).Union(
                //                                                                                               inbox.MessagePositionUsers.
                //                                                                                               Select(mp => new
                //                                                                                                            {
                //                                                                                                                mp.Id,
                //                                                                                                                mp.IsRead,
                //                                                                                                                mp.IsSender
                //                                                                                                            }));

                //var unreadMesInboxCount = unreadMesInbox.Where(m => m.IsSender == false && m.IsRead == false).Count();
                //var outbox = MessageFolderService.GetAll().First(m => m.OwnerId == userId && m.FolderType == 1);
                //var unreadMesOutboxCount = outbox.MessageExpertUsers.Select(mp => new
                //                                                                        {
                //                                                                            mp.Id,
                //                                                                            mp.IsRead,
                //                                                                            mp.IsSender
                //                                                                        }).Union(
                //                                                                          inbox.MessageCompanyUsers.
                //                                                                              Select(mp => new
                //                                                                                              {
                //                                                                                                  mp.Id,
                //                                                                                                  mp.IsRead,
                //                                                                                                  mp.IsSender
                //                                                                                                  })).Union(
                //                                                                                               inbox.MessagePositionUsers.
                //                                                                                               Select(mp => new
                //                                                                                                           {
                //                                                                                                               mp.Id,
                //                                                                                                               mp.IsRead,
                //                                                                                                               mp.IsSender
                //                                                                                                           })).
                //                                                                                                            Where(m => m.IsSender == false && m.IsRead == false).Count();
                //var trash = MessageFolderService.GetAll().First(m => m.OwnerId == userId && m.FolderType == 2);
                //var unreadMesTrashCount = trash.MessageExpertUsers.Select(mp => new
                //                                                                    {
                //                                                                        mp.Id,
                //                                                                        mp.IsRead,
                //                                                                        mp.IsSender
                //                                                                    }).Union(
                //                                                                          inbox.MessageCompanyUsers.
                //                                                                              Select(mp => new
                //                                                                              {
                //                                                                                  mp.Id,
                //                                                                                  mp.IsRead,
                //                                                                                  mp.IsSender
                //                                                                              })).Union(
                //                                                                                               inbox.MessagePositionUsers.
                //                                                                                               Select(mp => new
                //                                                                                               {
                //                                                                                                   mp.Id,
                //                                                                                                   mp.IsRead,
                //                                                                                                   mp.IsSender
                //                                                                                               })).
                //                                                                                                 Where(m => m.IsSender == false && m.IsRead == false).Count();
                //return Json(new {folders, unreadMesInboxCount, unreadMesOutboxCount, unreadMesTrashCount }, JsonRequestBehavior.AllowGet);
                #endregion

                return messageFolders;
            }

            catch (Exception ex)
            {
                log.Error(ex.Message + Environment.NewLine + "Stack: " + ex.StackTrace, ex);
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
        }

        //[System.Web.Mvc.HttpPost]
        //public JsonResult Save(MessageFolder messageFolder)
        //{
        //    ILog log = LogManager.GetLogger(GetType());
        //    try
        //    {
        //        var user = UserService.GetUserByUsername(User.Identity.Name);
        //        var foundFolder =
        //            MessageFolderService.GetAll().Where(m => m.OwnerId == user.Id && m.Name == messageFolder.Name);
        //        if (foundFolder.Count() == 0)
        //        {
        //            messageFolder.OwnerId = user.Id;
        //            messageFolder.FolderType = 3;
        //            MessageFolderService.SaveOrUpdate(messageFolder);

        //            return Json("Ok", JsonRequestBehavior.AllowGet);
        //        }
        //        return Json("Error", JsonRequestBehavior.AllowGet);
        //    }

        //    catch (Exception ex)
        //    {
        //        log.Error(ex.Message + Environment.NewLine + "Stack: " + ex.StackTrace, ex);
        //        return Json(new { Result = "ERROR", ex.Message }, JsonRequestBehavior.AllowGet);
        //    }
        //}
    }
}